package com.openlogic.common.logic.node.parse;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.noear.solon.core.event.AppBeanLoadEndEvent;
import org.noear.solon.core.event.EventListener;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.openlogic.common.logic.constants.NodeConstants;
import com.openlogic.common.logic.node.enums.ParseTypeEnums;

/**
* @ClassName: NodeParseAbstract
* @Description: 策略模式 NodeInfo节点解析处理器 策略接口
* @author weiyongpeng
* @date 2024年7月14日 上午10:54:07
 */
public abstract class BaseParseHandler implements EventListener<AppBeanLoadEndEvent>{
	
	/**
	* 描述：生成解析后的json字符串 模板方法
	* @Title: getResValue
	* @param ruleModelValue
	* @return
	* @author weiyongpeng
	* @date  2024年7月14日 下午12:33:29
	 */
	public String getResValue(String ruleModelValue) {
		return this.getNodeAndLineInfo(ruleModelValue);
	};
	
	/**
	* 描述 公共模板方法，用于组合不同节点以及连线数据，解析节点和线，返回特定字符串
	* @Title: getNodeAndLineInfo
	* @param ruleModelValue 原始json
	* @return
	* @author weiyongpeng
	* @date  2024年7月14日 上午10:54:55
	 */
	protected String getNodeAndLineInfo(String ruleModelValue) {
		Map<String, Map<?, List<?>>> result = new HashMap<String, Map<?, List<?>>>();
		JSONObject ruleJsonObject = JSON.parseObject(ruleModelValue);
		// 获取nodes数据集
		JSONObject nodeInfoJsonObject = JSON.parseObject(ruleJsonObject.get(NodeConstants.NODES_LABEL).toString());
		// 获取lines数据集
		JSONObject lineInfoJsonObject = JSON.parseObject(ruleJsonObject.get(NodeConstants.LINES_LABEL).toString());
		// 存放规则节点信息
		result.put(NodeConstants.NODE_INFO, ParseTypeEnums.NODE_INFO.getParseByType().setResultMap(nodeInfoJsonObject, lineInfoJsonObject));
		// 存放规则连线信息
		result.put(NodeConstants.LINE_INFO, ParseTypeEnums.LINE_INFO.getParseByType().setResultMap(nodeInfoJsonObject, lineInfoJsonObject));
		// 存放循环域信息
		result.put(NodeConstants.AREA_INFO, ParseTypeEnums.AREA_INFO.getParseByType().setResultMap(nodeInfoJsonObject, null));
		// 存字段类型
		result.put(NodeConstants.FIELD_INFO, ParseTypeEnums.FIELD_INFO.getParseByType().setResultMap(nodeInfoJsonObject, lineInfoJsonObject));

		return JSONObject.parseObject(JSON.toJSONString(result)).toString();
	}
	

	/**
	* 描述：公共模板方法，用于设置节点字段含义 公共方法
	* @Title: setFiledName
	* @param type
	* @return
	* @author weiyongpeng
	* @date  2024年7月14日 上午11:05:20
	 */
	protected List<String> setFiledName(String type) {
		List<String> resultList = new ArrayList<String>();
		if (NodeConstants.NODE_INFO.equals(type)) {
			resultList.add("id"); // 节点id
			resultList.add("name"); // 节点名称
			resultList.add("belongType");// 如果节点在循环域中，则取循环域的类型；如果不在循环域中，则取当前节点的类型
			resultList.add("data"); // 节点if、success、failed数据
			resultList.add("areaId"); // 如果节点在循环域中，则取循环域的id，否则为空
			resultList.add("type"); // 取当前节点的类型
			resultList.add("isAreaLastNode"); // 是否是循环域中的最后一个节点
			resultList.add("linesId"); // 与下级节点连线集合
			resultList.add("dataBind"); // 节点绑定的变量属性
		} else if (NodeConstants.LINE_INFO.equals(type)) {
			resultList.add("id"); // 线条id
			resultList.add("name"); // 线条名称
			resultList.add("type"); // 线条类型
			resultList.add("from"); // 线条开始端
			resultList.add("to"); // 线条结束端
			resultList.add("value"); // 线条上的判断条件值
		} else if (NodeConstants.AREA_INFO.equals(type)) {
			resultList.add("id"); // 循环域Id
			resultList.add("name"); // 循环域名称
			resultList.add("loopType"); // 循环类型，先判断或者后判断
			resultList.add("if"); // 循环判断条件
			resultList.add("dataBind"); // 节点绑定的变量属性
		} else if (NodeConstants.FIELD_INFO.equals(type)) {
			resultList.add("name:type"); // 字段名称：字段数据类型
		}

		return resultList;
	}
	
	/**
	* 描述：确定循环域中所有的规则的节点
	* @Title: getAreaNodeSeq 
	* @param nodeInfoJsonObject 节点数据
	* @return
	* @author weiyongpeng
	* @date  2024年7月14日 下午2:17:30
	 */
	protected Map<String, String> getAreaNodeSeq(JSONObject nodeInfoJsonObject) {
		Map<String, String> idMap = new HashMap<String, String>();
		getValue(nodeInfoJsonObject.toString(), idMap);
		Map<String, String> rs = new HashMap<String, String>();
		for (Map.Entry<String, String> entry : idMap.entrySet()) {
			JSONObject tmpObject = JSON.parseObject(entry.getValue().toString());
			if (!"area".equals(tmpObject.get("type").toString()))
				continue;
			String value = "";
			String id = tmpObject.get("id").toString();
			JSONObject object = JSON.parseObject(tmpObject.get("data").toString());
			Iterator<String> keys = object.keySet().iterator();
			while (keys.hasNext()) {
				String key = keys.next().toString();
				if(StringUtils.equals("parent", key)) {
					continue;
				}
				value = rs.get(id) == null ? "" : rs.get(tmpObject.get("id").toString()).toString();
				value += key + "#";
				rs.put(id, value);
			}
		}
		return rs;
	}

	/**
	* 描述：将json串中的数据转换到成Map对象的值
	* @Title: getValue
	* @param value
	* @param tempMap
	* @return
	* @author weiyongpeng
	* @date  2024年7月14日 下午2:18:31
	 */
	protected static Map<String, String> getValue(String value, Map<String, String> tempMap) {
		JSONObject jsonObject = JSON.parseObject(value);
		for (Object tempArray : jsonObject.entrySet()) {
			int tempLength = tempArray.toString().indexOf("=");
			String tempKey = tempArray.toString().substring(0, tempLength);
			String tempValue = tempArray.toString().substring(tempLength + 1);
			if (StringUtils.equals(tempKey, "parent")) {
				continue;
			}
			tempMap.put(tempKey, tempValue);
		}
		return tempMap;
	}
	
	/**
	* 描述：抽象逻辑，用于设置节点、线条、循环域和字段属性
	* @Title: setResultMap
	* @param type 				类型
	* @param nodeInfoJsonObject 节点数据
	* @param lineInfoJsonObject 线条数据
	* @return
	* @author weiyongpeng
	* @date  2024年7月14日 上午11:03:03
	 */
	protected abstract Map<Object, List<?>> setResultMap(JSONObject nodeInfoJsonObject,JSONObject lineInfoJsonObject);
	
	/**
	* 描述：抽象逻辑，用于获取解析后json中value的值（节点、线条、循环域、字段属性）
	* @Title: getAllLineInfo
	* @param lineInfoJsonObject
	* @param nodeInfoJsonObject
	* @return
	* @author weiyongpeng
	* @date  2024年7月14日 下午2:06:52
	 */
	protected abstract List<List<?>> getAllValueInfo(JSONObject lineInfoJsonObject,JSONObject nodeInfoJsonObject);
	
}
